﻿using System.Windows.Input;
using System.Windows.Media;
using uTrade.Core;

namespace uTrade.Controls
{
    public abstract class DrawObjBase : DrawingRegion
    {
        //当前可视区域的可显示条目个数
        protected int drawItemCount = 0;

        protected abstract int TotalItemCount { get; }

        //可显示区域的第一个在整体中的index
        protected int drawItemStartIndex = 0;

        //K线宽度
        protected int itemWidth = 6;

        //K线之间的间隙
        protected double itemSpace = 2;

        private double maxChartOffset = 0;
        public double chartOffset = 0;

        public delegate void RegionChangedHandler(object sender);

        public event RegionChangedHandler OnRegionChanged;

        public delegate void PriceChangedEventHandler(int index);

        public event PriceChangedEventHandler OnPriceChanged;

        //TEST
        public delegate void MouseMoveEventHandler(object sender, object obj);

        public event MouseMoveEventHandler OnTestMouseMove;

        protected abstract void DrawObj(DrawingContext dc);

        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            if (!InitDrawRegion())
            {
                return;
            }

            DrawObj(dc);

            OnRegionChanged?.Invoke(this);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            var pos = e.GetPosition(this);

            var sIndex = (int)((pos.X - ChartStartX) / ChartWidth * TotalItemCount);

            //OnTestMouseMove(this, pos);

            if (e.LeftButton == MouseButtonState.Pressed)
            {
                //if (!InChart(pos))
                //{
                //    chartOffset += mousePos.X - pos.X;
                //}
                //else
                {
                    //do our time line select task. infact we just change our chartOffset
                    //calc start index in time space.
                    var startIndex = (int)((pos.X - ChartStartX) / ChartWidth * TotalItemCount);
                    chartOffset = startIndex * (itemWidth + itemSpace) - ChartWidth / 2.0;
                }
                OnRegionChanged?.Invoke(this);
                this.InvalidateVisual();
            }

            if (chartOffset < 0)
            {
                chartOffset = 0;
            }
            maxChartOffset = GetMaxOffset();
            if (chartOffset > maxChartOffset)
            {
                chartOffset = maxChartOffset;
            }

            //TODO 在时间区里，直接返回
            //if (eIndType == IndicatorType.Time)
            //{
            //    return;
            //}
            //Point point = Mouse.GetPosition(this);
            if (e.LeftButton != MouseButtonState.Pressed)
            {
                var itemIndex = (int)((chartOffset + pos.X) / (itemWidth + itemSpace));
                if (itemIndex < TotalItemCount)
                {
                    //tell listener that price item changed.
                    OnPriceChanged?.Invoke(itemIndex);
                }
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            var pos = e.GetPosition(this);

            if (!InChart(pos))
            {
                return;
            }

            //in timeline area
            //var startIndex = (int)((x - ChartStartX) / ChartWidth * TotalItemCount);
            //chartOffset = startIndex * (itemWidth + itemSpace) - ChartWidth / 2.0;

            //maxChartOffset = GetMaxOffset();
            //if (chartOffset > maxChartOffset)
            //{
            //    chartOffset = maxChartOffset;
            //}
            //if (chartOffset < 0)
            //{
            //    chartOffset = 0;
            //}
            this.InvalidateVisual();
        }

        //计算可视区域的始末
        private bool InitDrawRegion()
        {
            //确定偏移量
            maxChartOffset = GetMaxOffset();
            if (chartOffset > maxChartOffset)
            {
                chartOffset = maxChartOffset;
            }
            if (chartOffset < 0)
            {
                chartOffset = 0;
            }

            //显示的记录个数和开始序号
            drawItemCount = (int)(ChartWidth / (itemWidth + itemSpace));
            drawItemStartIndex = (int)(chartOffset / (itemWidth + itemSpace));
            if (drawItemStartIndex >= TotalItemCount)
            {
                return false;
            }
            //微调显示的个数，确保能显示完全
            if (drawItemStartIndex + drawItemCount > TotalItemCount)
            {
                drawItemCount = TotalItemCount - drawItemStartIndex - 1;
            }
            //确定纵坐标范围
            return true;
        }

        //可显示区域的前面还有多长
        private double GetMaxOffset()
        {
            //可显示的K线的数量
            var cnt = this.ChartWidth / (itemWidth + itemSpace);

            //整个中间部分的宽度（不可见部分）即显示的第一个记录在总记录中的位置（换算成长度）
            var offset = (TotalItemCount - cnt) * (itemWidth + itemSpace);
            if (offset < 0)   //总记录数不满一屏
            {
                offset = 0;
            }
            return offset + 6;  //末尾不贴到边界
        }

        private DataSeries GetCurSerise(DataSeries ds)
        {
            DataSeries subds = new DataSeries();
            for (int i = drawItemStartIndex; i < drawItemStartIndex + drawItemCount; i++)
            {
                subds.Add(ds[i]);
            }
            return subds;
        }

        //定义笔
        public Pen GetPen(byte r, byte g, byte b, double thickness, byte a = 255)
        {
            Pen pen = new Pen();
            Color penColor = Color.FromArgb(a, r, g, b);
            pen.Brush = new SolidColorBrush(penColor);
            pen.Thickness = thickness;
            return pen;
        }
    }
}